home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / XML Utilities / Professional Programmer XSL IDE / Xselerator25.msi / Data.Cab / F44206_transformandsum.txt < prev    next >
Encoding:
Text File  |  2002-02-06  |  2.6 KB  |  85 lines

  1. > Here are three ways to sum over a computed quantity:
  2. > * Create a result tree fragment containing nodes whose value is the computed
  3. > number, and use sum(xx:node-set($rtf//value)) to do the summation, where
  4. > xx:node-set() is your vendor's extension function for converting an RTF to a
  5. > node-set
  6. > * Use a recursive named template [this is the only standard XSLT 1.0
  7. > solution]
  8. > * Use the xalan extension function xalan:sum($nodes, xalan:expression(...))
  9.  
  10. > > I want to sum the "freespace", but sum(//disk/freespace)
  11. > > won't work because
  12. > > freespace is not a number due to the trailing "MB".
  13.  
  14. The first of the above solutions requires inappropriate amount of memory and time.
  15.  
  16. The third ties us to a proprietary (although one of the best) XSLT processor.
  17.  
  18. The second is too-general, as one can achieve almost anything in XSLT with recursion. It would be almost equivalent to say: "Use arithmetic rules".
  19.  
  20. Here's another, more practical way, since it uses a "library function" -- transformAndSum:
  21.  
  22. http://sources.redhat.com/ml/xsl-list/2001-11/msg00831.html
  23.  
  24. This is ***the*** general solution for all such problems belonging to this "transform and sum" class of problems...
  25.  
  26. Having such a general solution available in pure XSLT shows that any "dynamic module" effort is very limited and therefore not applicable (== of any use) in the general cases.
  27.  
  28. Re-Using the ready-made "transform and sum" function described in the above link gives us the following:
  29.  
  30. <xsl:stylesheet version="1.0"
  31. xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  32. xmlns:func-transform="f:func-transform"
  33. exclude-result-prefixes="xsl func-transform"
  34. >
  35.    <xsl:import href="transform-and-sum.xsl"/>
  36.  
  37.    <xsl:output method="text"/>
  38.    
  39.    <func-transform:func-transform/>
  40.  
  41.     <xsl:template match="/">
  42.       <xsl:call-template name="transform-and-sum">
  43.         <xsl:with-param name="pFuncTransform" 
  44.                         select="document('')/*/func-transform:*[1]"/>
  45.         <xsl:with-param name="pList" select="//freespace"/>
  46.       </xsl:call-template>
  47.     </xsl:template>
  48.     
  49.     <xsl:template match="func-transform:*">
  50.       <xsl:param name="arg" select="0"/>
  51.       <xsl:value-of select="substring-before($arg, ' ')"/>
  52.     </xsl:template>
  53.  
  54. </xsl:stylesheet>
  55.  
  56.  
  57. When this transformation is applied on the following (your) source xml:
  58.  
  59. <disks>
  60.   <disk>
  61.     <freespace>1235 MB</freespace>
  62.   </disk>
  63.   <disk>
  64.     <freespace>40 MB</freespace>
  65.   </disk>
  66.   <disk>
  67.     <freespace>75 MB</freespace>
  68.   </disk>
  69. </disks>
  70.  
  71. The result is:
  72.  
  73. 1350
  74.  
  75.  
  76. Hope this helped.
  77.  
  78. Cheers,
  79. Dimitre Novatchev.
  80.  
  81.  
  82.